/**
 * @file FFmpegWrapper.h
 * @brief FFmpeg视频处理封装类
 * 
 * 该类封装了FFmpeg的视频解码、编码和推流功能，提供了线程安全的视频帧处理机制。
 * 支持RTSP流媒体输入和RTMP推流输出。
 */

#ifndef FFMPEGWRAPPER_H
#define FFMPEGWRAPPER_H

// 系统头文件
#include <string>
#include <thread>
#include <memory>

// 项目头文件
#include "ThreadSafeQueue.h"

// FFmpeg库头文件
extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

/**
 * @brief 视频帧数据结构
 */
struct FrameData
{
    AVFrame *frame;     ///< FFmpeg帧对象指针
    int64_t pts;        ///< 显示时间戳
};

/**
 * @brief FFmpeg视频处理封装类
 * 
 * 该类提供了视频流的解码、处理、编码和推流功能，支持断线重连机制。
 */
class FFmpegWrapper
{
public:
    FFmpegWrapper();
    ~FFmpegWrapper();

    /**
     * @brief 打开视频流
     * @param url 视频流地址（如RTSP地址）
     * @return 成功返回true，失败返回false
     */
    bool open(const std::string &url);

    /**
     * @brief 关闭视频流并释放资源
     */
    void close();

    /**
     * @brief 检查是否正在运行
     * @return 正在运行返回true，否则返回false
     */
    bool isRunning() const;

    /**
     * @brief 获取一帧视频数据
     * @return FrameData结构体
     */
    FrameData getFrame();

    /**
     * @brief 获取视频宽度
     * @return 视频宽度（像素）
     */
    int getWidth() const;

    /**
     * @brief 获取视频高度
     * @return 视频高度（像素）
     */
    int getHeight() const;

    /**
     * @brief 设置推流参数
     * @param output_url 推流地址（如RTMP地址）
     * @param bitrate 视频码率（bps）
     * @param fps 视频帧率
     */
    void setStreamParams(const std::string &output_url, int bitrate, int fps);

    /**
     * @brief 初始化编码器
     * @return 成功返回true，失败返回false
     */
    bool initEncoder();

private:
    // 编码推流相关成员变量
    AVFormatContext *ofmt_ctx_; ///< 输出格式上下文
    AVCodecContext *enc_ctx_;   ///< 编码器上下文
    AVStream *video_st_;        ///< 视频流
    std::string output_url_;    ///< 推流地址
    int bitrate_;               ///< 视频码率
    int fps_;                   ///< 视频帧率
    bool encoding_;             ///< 编码状态
    bool streaming_;            ///< 推流状态
    std::thread encode_thread_; ///< 编码线程
    std::thread stream_thread_; ///< 推流线程

    /**
     * @brief 编码线程函数
     */
    void encodeThreadFunc();

    /**
     * @brief 推流线程函数
     */
    void streamThreadFunc();

protected:
    /**
     * @brief 处理视频帧（可被子类重写）
     * @param frame 视频帧数据
     */
    virtual void processFrame(const FrameData &frame);

private:
    bool initDecoder(AVDictionary *&opts);
    void decodeThreadFunc();
    void processThreadFunc();
    void cleanup();
    int reconnect();

    std::string url_;           ///< 输入流地址
    AVFormatContext *format_ctx_; ///< 输入格式上下文
    AVCodecContext *codec_ctx_; ///< 解码器上下文
    AVFrame *frame_;            ///< 解码帧
    AVPacket *packet_;          ///< 数据包
    int video_stream_index_;    ///< 视频流索引
    int width_;                 ///< 视频宽度
    int height_;                ///< 视频高度

protected:
    struct SwsContext *sws_ctx_; ///< 图像缩放转换上下文

private:
    ThreadSafeQueue<FrameData> frame_queue_; ///< 解码帧队列
    ThreadSafeQueue<FrameData> encode_queue_; ///< 编码帧队列
    std::thread decode_thread_; ///< 解码线程
    std::thread process_thread_; ///< 处理线程
    bool running_;              ///< 运行状态
    bool process_running_;      ///< 处理线程状态

    int max_reconnect_attempts_; ///< 最大重连次数
    int current_reconnect_attempts_; ///< 当前重连次数
    int reconnect_interval_;     ///< 重连间隔时间（秒）
    bool reconnecting_;          ///< 重连状态
    AVDictionary *opts = nullptr; ///< FFmpeg选项
};

#endif // FFMPEGWRAPPER_H
